package blockencryption;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Encryptor {
	static Cipher cipher;
	static {
		try {
			cipher = Cipher.getInstance("AES/ECB/NoPadding");
		} catch (NoSuchAlgorithmException e) {
			// will not be the case
		} catch (NoSuchPaddingException e) {
			// will not be the case
		}
	}

	static byte[] generateKey() {
		try {
			// Get the KeyGenerator
			KeyGenerator kgen = KeyGenerator.getInstance("AES");
			kgen.init(128); // 192 and 256 bits may not be available

			// Generate the secret key specs.
			SecretKey skey = kgen.generateKey();
			byte[] key = skey.getEncoded();
			return key;
		} catch (NoSuchAlgorithmException e) {
			System.out.println("Algorithm \"AES\" not supported.");
		}
		return new byte[16];
	}

	static int[] cipher(int[] input, byte[] key, boolean encrypt)
			throws BadPaddingException {
		byte[] data = convertIntArrayToByteArray(input);
		byte[] output = null;
		SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
		try {
			int opmode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
			cipher.init(opmode, keySpec);
			output = cipher.doFinal(data);
			return convertByteArrayToIntArray(output);
		} catch (InvalidKeyException e) {
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	private static int[] convertByteArrayToIntArray(byte[] data) {
		ByteBuffer byteBuffer = ByteBuffer.wrap(data);
		IntBuffer intBuffer = byteBuffer.asIntBuffer();
		int[] output = new int[data.length / 4];
		intBuffer.get(output);
		return output;
	}

	private static byte[] convertIntArrayToByteArray(int[] data) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);
		IntBuffer intBuffer = byteBuffer.asIntBuffer();
		intBuffer.put(data);
		return byteBuffer.array();
	}
}
